﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading.Tasks;

namespace KnowledgeAssistant
{
    public partial class StudentsForm : Form
    {
        public enum ActionType { login, pass }
        public ActionType act_type;
        static List<Student> students;
        static Group g = null;

        public StudentsForm()
        {
            InitializeComponent();
            //group_comboBox.SelectedIndexChanged -= group_comboBox_SelectedIndexChanged;
            InitData();
        }

        private void StudentsForm_Load(object sender, EventArgs e)
        {

        }

        private void InitData()
        {
            students_dataGridView.AutoGenerateColumns = false;

            List<Group> groups =GroupUtil.GetAllGroups();
            groups.Add(new Group(0, "Все", "", 1));
            group_comboBox.DataSource = groups;
            group_comboBox.DisplayMember = "FullName";    
           
        }

        private void FindStudents()
        {
            if (group_comboBox.SelectedIndex != -1)
            {
                g = (Group)group_comboBox.SelectedItem;
                students = StudentUtil.GetListStudentsWithUserData(g);
                
                students_dataGridView.DataSource = students;
                students_dataGridView.Columns[0].DataPropertyName = "FullName";
                students_dataGridView.Columns[1].DataPropertyName = "GroupNumber";
                students_dataGridView.Columns[2].DataPropertyName = "Username";
                students_dataGridView.Columns[3].DataPropertyName = "Password";                
            }
        }                        

        private void button1_Click(object sender, EventArgs e)
        {
            FindStudents();
        }

        private void button2_Click(object sender, EventArgs e)
        {
            EditStudentForm esf = new EditStudentForm(g);
            esf.ShowDialog();
            FindStudents();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            if (students_dataGridView.SelectedRows.Count > 0)
            {
                EditStudentForm esf = new EditStudentForm(students[students_dataGridView.SelectedRows[0].Index]);
                esf.ShowDialog();
                FindStudents();
            }
        }

        private void button4_Click(object sender, EventArgs e)  //и здесь
        {
            if (students_dataGridView.SelectedRows.Count > 0)
            {
                Boolean found = false;
                DataTable usertable = null;
                int user_id = 0;
                usertable = DatabaseConnect.execQuery("SELECT owner_id, user_id FROM Users").Tables[0];
                if (usertable != null)
                {
                    foreach (DataRow row in usertable.Rows)
                    {
                        int owner_id = 0;
                        Int32.TryParse(row["owner_id"].ToString(), out owner_id);

                        if (owner_id == students[students_dataGridView.SelectedRows[0].Index].StudentID)
                        {
                            found = true;
                            user_id = (int)row["user_id"];
                        }
                    }
                }

                if (found)
                {
                    DialogResult dr = MessageBox.Show("У выбранного студента имеются логин и пароль. Вы настаиваете на полном удалении?", "Удаление студента", MessageBoxButtons.YesNo);
                    if (dr == System.Windows.Forms.DialogResult.Yes)
                    {
                        UserUtil.DeleteUser(user_id);
                        StudentUtil.DeleteStudent(students[students_dataGridView.SelectedRows[0].Index]);
                    }
                }
                else
                {
                    DialogResult dr = MessageBox.Show("Удалить студента из таблицы?", "Удаление студента", MessageBoxButtons.YesNo);
                    if (dr == System.Windows.Forms.DialogResult.Yes)
                    {
                        StudentUtil.DeleteStudent(students[students_dataGridView.SelectedRows[0].Index]);
                    }
                }
                FindStudents();
            }
        }

        private void group_comboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (group_comboBox.SelectedIndex != -1)
            {
                g = (Group)group_comboBox.SelectedValue;
                FindStudents();
                if (g.GroupID == 0) 
                {
                    button1.Enabled = false;
                    new_group_button.Enabled = true;
                    edit_group_button.Enabled = false;
                    import_students.Enabled = false;
                }
                else
                {
                    button1.Enabled = true;
                    new_group_button.Enabled = true;
                    edit_group_button.Enabled = true;
                    import_students.Enabled = true;
                }
            }
        }

        public static string generateRandomString(ActionType act_type)
        {
            Random rnd = new Random();
            int value = 0;
            string gen_string = "";
            
            if (act_type == ActionType.pass)
            for (int i = 0; i < 5; i++)
                switch (rnd.Next(3))
                {
                    case 0:
                        {
                            value = rnd.Next(48, 58);
                            char rand_char = (char)value;
                            gen_string += rand_char;
                        }
                        break;
                    case 1:
                        {
                            value = rnd.Next(65, 91);
                            char rand_char = (char)value;
                            gen_string += rand_char;
                        }
                        break;
                    case 2:
                        {
                            value = rnd.Next(97, 123);
                            char rand_char = (char)value;
                            gen_string += rand_char;
                        }
                        break;
                }
            if (act_type == ActionType.login)
                for (int i = 0; i < 4; i++)
                {
                    value = rnd.Next(97, 123);
                    char rand_char = (char)value;
                    gen_string += rand_char;
                }
            if (checkExistUser(gen_string)) generateRandomString(ActionType.login);
            return gen_string;
        }

        private static void InitXmlStudentsList(string fileName)
        {
            #region Описание переменных
            StreamReader sr = new StreamReader(fileName);
            Student s = null;
            int count_processed_lines = 0;
            string error_lines = "";
            string notAdded = "";
            Boolean groupExist = false;
            string line = "";
            string group = "";
            string lname = "";
            string mname = "";
            string fname = "";
            int recbook = 0;
            string userName = "";
            string userPass = "";
            #endregion

            while (!sr.EndOfStream && !groupExist) //Вход в файл, пока не встретится группа
            {
                line = sr.ReadLine(); count_processed_lines++;

                if (line != "" && line.Contains("<group>") && line.Contains("</group>"))
                {
                    group = parse_XmlTag(line, "group").Trim();

                    if (group == g.GroupNumber)
                    {
                        int count_saved_students = 0;                        
                        int user_exist_number = 0;
                        groupExist = true;
                        line = sr.ReadLine(); count_processed_lines++;

                        while (!sr.EndOfStream && !line.Contains("<teacher>") && (!line.Contains("<group>") || !line.Contains("</group>"))) //пока не будет достигнут
                        {
                            Boolean error = false;
                            line = sr.ReadLine(); count_processed_lines++;

                            #region Проход по найденной группе и парсинг каждого студента
                            if (!error && line != "" && line.Contains("<lname>") && line.Contains("</lname>"))
                            {
                                Boolean studentReaded = false;
                                Boolean tag_fname = false;
                                Boolean tag_mname = false;
                                Boolean tag_recbook = false;

                                lname = parse_XmlTag(line, "lname").Trim();
                                line = sr.ReadLine(); count_processed_lines++;

                                while (!sr.EndOfStream && !line.Contains("<fname>") && !line.Contains("</fname>")
                                    && !line.Contains("<group>") && !line.Contains("<teacher>") && !line.Contains("<mname>") && !line.Contains("<recbook>"))
                                {
                                    line = sr.ReadLine(); count_processed_lines++;
                                }
                                if (line != "" && line.Contains("<fname>") && line.Contains("</fname>")
                                    && !line.Contains("<teacher>") && !line.Contains("<group>") && !line.Contains("<mname>") && !line.Contains("<recbook>"))
                                {
                                    fname = parse_XmlTag(line, "fname").Trim();
                                    tag_fname = true;
                                    line = sr.ReadLine(); count_processed_lines++;
                                }
                                if (!tag_fname)
                                {
                                    MessageBox.Show("Не найдено имя для студента " + lname + " в файле XML! \nНомер строки с ошибкой: " + count_processed_lines);
                                    error_lines += count_processed_lines + ", ";
                                }

                                while (!sr.EndOfStream && tag_fname && !line.Contains("<mname>") && !line.Contains("</mname>")
                                    && !line.Contains("<group>") && !line.Contains("<teacher>") && !line.Contains("<recbook>"))
                                {
                                    line = sr.ReadLine(); count_processed_lines++;
                                }
                                if (tag_fname && line != "" && (line.Contains("<mname>") && line.Contains("</mname>"))
                                    && !line.Contains("<teacher>") && !line.Contains("<group>") && !line.Contains("<recbook>"))
                                {
                                    mname = parse_XmlTag(line, "mname").Trim();
                                    tag_mname = true;
                                    line = sr.ReadLine(); count_processed_lines++;
                                }
                                if (!tag_mname && tag_fname)
                                {
                                    MessageBox.Show("Не найдено отчество для студента " + lname + " " + fname + " в файле XML! \nНомер строки с ошибкой: " + count_processed_lines);
                                    error_lines += count_processed_lines + ", ";
                                }

                                while (!sr.EndOfStream && tag_mname && !line.Contains("<recbook>") && !line.Contains("</recbook>")
                                    && !line.Contains("<teacher>") && !line.Contains("<group>"))
                                {
                                    line = sr.ReadLine(); count_processed_lines++;
                                }
                                if (tag_mname && line.Contains("<recbook>") && line.Contains("</recbook>")
                                    && !line.Contains("<teacher>") && !line.Contains("<group>"))                          
                                {
                                    if (Int32.TryParse(parse_XmlTag(line, "recbook").Trim(), out recbook))
                                    {
                                        tag_recbook = true;
                                        userName = generateRandomString(ActionType.login);
                                        userPass = generateRandomString(ActionType.pass);
                                        line = sr.ReadLine(); count_processed_lines++;
                                    }
                                }
                                if (!tag_recbook && tag_mname && tag_fname)
                                {
                                    MessageBox.Show("Не распознан номер зач. книжки для студента " + lname + " " + fname + " " + mname + " в файле XML! \nНомер строки с ошибкой: " + count_processed_lines);
                                    error_lines += count_processed_lines + ", ";
                                }

                                studentReaded = tag_fname && tag_mname && tag_recbook;
                                if (studentReaded)
                                {
                                    if (!checkExistStudentFullName(lname, fname, mname) && !checkExistUser(userName))
                                    {
                                        s = new Student();
                                        s.Group = g;
                                        s.LastName = lname;
                                        s.FirstName = fname;
                                        s.MiddleName = mname;
                                        s.RecordBookNumber = recbook;
                                        StudentUtil.SaveStudent(s);

                                        DataTable table = DatabaseConnect.execSP("GetStudent", new List<string>() { 0.ToString() }).Tables[0];
                                        int s_id = 0;
                                        foreach (DataRow r in table.Rows)
                                        {
                                            s_id = int.Parse(r["student_id"].ToString());
                                        }
                                        UserUtil.AddUser(userName, userPass, 6, s_id, 1);
                                        count_saved_students++;
                                    }
                                    else
                                    {
                                        user_exist_number++;
                                        notAdded += "\n" + lname + " " + fname + " " + mname + " с логином " + userName + " и зачетной книжкой " + recbook;
                                        line = sr.ReadLine(); count_processed_lines++;
                                    }
                                }
                            }
                            else // если lname не встретился
                                if (line != "" && (line.Contains("<lname>") || line.Contains("</lname>")) && !line.Contains("<teacher>"))
                                {
                                    MessageBox.Show("Найден неопознанный студент в файле XML! \nНомер строки с ошибкой: " + count_processed_lines);
                                    error = true;
                                }
                            #endregion                             
                        }
                        if (count_saved_students == 0 && user_exist_number != 0) MessageBox.Show(user_exist_number + " студентов уже присутствуют в списке:\n" + notAdded);
                        if (count_saved_students != 0 && user_exist_number == 0) MessageBox.Show(count_saved_students + " распознанных студентов успешно добавлены");
                        if (count_saved_students != 0 && user_exist_number != 0) MessageBox.Show(
                            user_exist_number + " студентов уже присутствуют в списке:\n" + notAdded + "\n\n" + count_saved_students + " распознанных студентов успешно добавлены");
                        if (count_saved_students == 0 && user_exist_number == 0) MessageBox.Show("Распознанных студентов не имеется");
                    }
                }
            }
            if (!groupExist) MessageBox.Show("Выбранный файл не содержит требуемой информации по текущей группе!");
            sr.Close();
        }
 
        private void button5_Click(object sender, EventArgs e)
        {
            PrintPreviewForm ppf = new PrintPreviewForm(g);
            ppf.ShowDialog();
        }

        private void button6_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Файлы разметки XML|*.xml";
            ofd.ShowDialog();
            if (ofd.FileName != "" && ofd.FileName != null)
            {
                InitXmlStudentsList(ofd.FileName);
                FindStudents();
            }                        
        }

        private void edit_group_button_Click(object sender, EventArgs e)
        {
            g = (Group)group_comboBox.SelectedValue;
            if (g != null)
            {
                int group = ((Group)group_comboBox.SelectedValue).GroupID;
                EditGroupNumberForm egnf = new EditGroupNumberForm(g, EditGroupNumberForm.ActionType.edit);
                egnf.ShowDialog();
                InitData();
                int i = 0;
                foreach (Group gr in group_comboBox.Items)
                {
                    if (gr.GroupID == group)
                    {
                        break;
                    }
                    i++;
                }
                this.group_comboBox.SelectedIndex = i;
            }
        }

        private void new_group_button_Click(object sender, EventArgs e)
        {
            EditGroupNumberForm egnf = new EditGroupNumberForm(EditGroupNumberForm.ActionType.add);
            egnf.ShowDialog();
            InitData();
            DataTable usertable = DatabaseConnect.execQuery("select MAX(group_id) as id from Groups").Tables[0];
            int id = (int)usertable.Rows[0]["id"];
            int i = 0;
            foreach (Group gr in group_comboBox.Items)
            {
                if (gr.GroupID == id)
                {
                    break;
                }
                i++;
            }
            this.group_comboBox.SelectedIndex = i;
        }

        public static string parse_XmlTag(string line, string tag)
        {
            string content = "";
            int start = 0;
            int end = 0;
            start = line.IndexOf("<" + tag + ">") + tag.Length + 2;
            end = line.IndexOf("</" + tag + ">");
            return content = line.Substring(start, end - start);
        }

        public static Boolean checkExistStudentFullName(string lname, string fname, string mname)
        {
            List<Student> students = StudentUtil.GetListStudentsForCheckExist(g);          
            if (students.Count != 0)
            {
                foreach (Student s in students)
                {
                    if ((s.LastName == lname) && (s.FirstName == fname) && (s.MiddleName == mname))
                        return true;
                }
            }
            return false;
        }

        public static Boolean checkExistUser(string uname)
        {
            DataTable usertable = null;
            usertable = DatabaseConnect.execQuery("SELECT user_name FROM Users where ISNULL(is_deleted,0) = 0").Tables[0];

            foreach (DataRow row in usertable.Rows)
            {
                if ((string)row["user_name"] == uname) return true;
            }

            return false;
        }
        
        private void button1_Click_1(object sender, EventArgs e)
        {
            if (group_comboBox.SelectedIndex != -1)
            {
                int index = group_comboBox.SelectedIndex;
                g = (Group)group_comboBox.SelectedItem;
                students = StudentUtil.GetListStudentsWithUserData(g);
                if (students.Count != 0)
                {
                    DialogResult dr = MessageBox.Show("Вы действительно хотете удалить группу со всеми студентами, привязанными к ним пользователями и результатами прохождения тестов?", "Удаление группы", MessageBoxButtons.YesNo);
                    if (dr == System.Windows.Forms.DialogResult.Yes) 
                    {
                        GroupUtil.DeleteGroup(g);
                        InitData();
                        if (group_comboBox.Items.Count != 0)
                        {
                            group_comboBox.SelectedIndex = index - 1;
                        }      
                    }
                }
                else
                {
                    GroupUtil.DeleteGroup(g);
                    InitData();
                    if (group_comboBox.Items.Count != 0)
                    {
                        group_comboBox.SelectedIndex = index - 1;
                    }      
                }                         
            }           
        }

        private void panel3_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
